/**
 * 主密码管理工具
 */

import { createCrypto, EncryptMethod } from './crypto'
import type { Account } from '@/api/account'

export interface MasterPasswordChangeResult {
  success: boolean
  reencryptedCount: number
  failedAccounts: number[]
  errors: string[]
}

/**
 * 修改主密码并重新加密所有账号数据
 */
export async function changeMasterPassword(
  oldPassword: string,
  newPassword: string,
  accounts: Account[],
  encryptMethod: EncryptMethod = EncryptMethod.AES_256_GCM
): Promise<MasterPasswordChangeResult> {

  const result: MasterPasswordChangeResult = {
    success: true,
    reencryptedCount: 0,
    failedAccounts: [],
    errors: []
  }

  try {
    // 创建旧密码的加密工具
    const oldCrypto = createCrypto({
      masterPassword: oldPassword,
      method: encryptMethod
    })

    // 创建新密码的加密工具
    const newCrypto = createCrypto({
      masterPassword: newPassword,
      method: encryptMethod
    })

    // 重新加密每个账号
    for (const account of accounts) {
      try {
        // 使用旧密码解密
        const decryptedData = {
          username: account.username_encrypted ? oldCrypto.decrypt(account.username_encrypted) : '',
          password: account.password_encrypted ? oldCrypto.decrypt(account.password_encrypted) : '',
          notes: account.notes_encrypted ? oldCrypto.decrypt(account.notes_encrypted) : ''
        }

        // 使用新密码重新加密
        account.username_encrypted = decryptedData.username ? newCrypto.encrypt(decryptedData.username) : ''
        account.password_encrypted = decryptedData.password ? newCrypto.encrypt(decryptedData.password) : ''
        account.notes_encrypted = decryptedData.notes ? newCrypto.encrypt(decryptedData.notes) : ''

        result.reencryptedCount++

      } catch (error) {
        result.failedAccounts.push(account.id)
        result.errors.push(`账号 ${account.title} 重新加密失败: ${error}`)
        result.success = false
      }
    }

  } catch (error) {
    result.success = false
    result.errors.push(`主密码修改失败: ${error}`)
  }

  return result
}

/**
 * 验证主密码
 */
export function validateMasterPassword(
  password: string,
  testData: string,
  encryptMethod: EncryptMethod = EncryptMethod.AES_256_GCM
): boolean {
  try {
    const crypto = createCrypto({
      masterPassword: password,
      method: encryptMethod
    })

    // 尝试解密测试数据
    crypto.decrypt(testData)
    return true

  } catch (error) {
    return false
  }
}

/**
 * 生成主密码提示
 */
export function generateMasterPasswordHint(password: string): string {
  // 生成一个安全的提示，不直接暴露密码信息
  const length = password.length
  const firstChar = password[0]
  const hasNumbers = /\d/.test(password)
  const hasSpecialChars = /[!@#$%^&*()_+\-=\[\]{};':"\\|,.<>\/?]/.test(password)

  const hints: string[] = []

  hints.push(`长度: ${length}位`)

  if (firstChar) {
    const type = /[a-z]/.test(firstChar) ? '小写字母' :
                 /[A-Z]/.test(firstChar) ? '大写字母' :
                 /\d/.test(firstChar) ? '数字' : '特殊字符'
    hints.push(`首字符: ${type}`)
  }

  if (hasNumbers) {
    hints.push('包含数字')
  }

  if (hasSpecialChars) {
    hints.push('包含特殊字符')
  }

  return hints.join(', ')
}

/**
 * 主密码强度要求
 */
export const MASTER_PASSWORD_REQUIREMENTS = {
  minLength: 12,
  requireUppercase: true,
  requireLowercase: true,
  requireNumbers: true,
  requireSpecialChars: true,
  disallowCommon: true
}

/**
 * 验证主密码是否符合要求
 */
export function validateMasterPasswordRequirements(password: string): {
  valid: boolean
  errors: string[]
} {
  const errors: string[] = []

  if (password.length < MASTER_PASSWORD_REQUIREMENTS.minLength) {
    errors.push(`密码长度至少为 ${MASTER_PASSWORD_REQUIREMENTS.minLength} 位`)
  }

  if (MASTER_PASSWORD_REQUIREMENTS.requireUppercase && !/[A-Z]/.test(password)) {
    errors.push('必须包含大写字母')
  }

  if (MASTER_PASSWORD_REQUIREMENTS.requireLowercase && !/[a-z]/.test(password)) {
    errors.push('必须包含小写字母')
  }

  if (MASTER_PASSWORD_REQUIREMENTS.requireNumbers && !/\d/.test(password)) {
    errors.push('必须包含数字')
  }

  if (MASTER_PASSWORD_REQUIREMENTS.requireSpecialChars &&
      !/[!@#$%^&*()_+\-=\[\]{};':"\\|,.<>\/?]/.test(password)) {
    errors.push('必须包含特殊字符')
  }

  if (MASTER_PASSWORD_REQUIREMENTS.disallowCommon) {
    const commonPatterns = ['password', '123456', 'qwerty', 'admin']
    const lowerPassword = password.toLowerCase()

    if (commonPatterns.some(pattern => lowerPassword.includes(pattern))) {
      errors.push('不能包含常见密码模式')
    }
  }

  return {
    valid: errors.length === 0,
    errors
  }
}

/**
 * 主密码锁定管理
 */
export class MasterPasswordLock {
  private static instance: MasterPasswordLock
  private lockTimeout: number = 30 * 60 * 1000 // 30分钟
  private lastActivityTime: number = Date.now()
  private isLocked: boolean = false
  private lockTimer: number | null = null

  private constructor() {
    this.startLockTimer()
  }

  static getInstance(): MasterPasswordLock {
    if (!MasterPasswordLock.instance) {
      MasterPasswordLock.instance = new MasterPasswordLock()
    }
    return MasterPasswordLock.instance
  }

  /**
   * 更新活动时间
   */
  updateActivity(): void {
    this.lastActivityTime = Date.now()
    this.isLocked = false
    this.startLockTimer()
  }

  /**
   * 检查是否已锁定
   */
  checkLocked(): boolean {
    const now = Date.now()
    if (now - this.lastActivityTime > this.lockTimeout) {
      this.isLocked = true
    }
    return this.isLocked
  }

  /**
   * 手动锁定
   */
  lock(): void {
    this.isLocked = true
    if (this.lockTimer) {
      clearTimeout(this.lockTimer)
    }
  }

  /**
   * 解锁
   */
  unlock(): void {
    this.isLocked = false
    this.updateActivity()
  }

  /**
   * 设置锁定超时时间（分钟）
   */
  setLockTimeout(minutes: number): void {
    this.lockTimeout = minutes * 60 * 1000
    this.startLockTimer()
  }

  /**
   * 启动锁定计时器
   */
  private startLockTimer(): void {
    if (this.lockTimer) {
      clearTimeout(this.lockTimer)
    }

    this.lockTimer = window.setTimeout(() => {
      this.lock()
    }, this.lockTimeout)
  }

  /**
   * 获取剩余时间（秒）
   */
  getRemainingTime(): number {
    const elapsed = Date.now() - this.lastActivityTime
    const remaining = this.lockTimeout - elapsed
    return Math.max(0, Math.floor(remaining / 1000))
  }
}

/**
 * 主密码存储（仅会话期间，不持久化）
 */
export class MasterPasswordSession {
  private static masterPassword: string | null = null

  /**
   * 设置主密码（仅存储在内存中）
   */
  static set(password: string): void {
    this.masterPassword = password
    MasterPasswordLock.getInstance().updateActivity()
  }

  /**
   * 获取主密码
   */
  static get(): string | null {
    const lock = MasterPasswordLock.getInstance()

    if (lock.checkLocked()) {
      this.clear()
      return null
    }

    lock.updateActivity()
    return this.masterPassword
  }

  /**
   * 清除主密码
   */
  static clear(): void {
    this.masterPassword = null
  }

  /**
   * 检查是否已设置
   */
  static has(): boolean {
    return this.masterPassword !== null && !MasterPasswordLock.getInstance().checkLocked()
  }
}
